﻿using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;

namespace OpenLS.Spreadsheet
{
    struct CellClusterKey
    {
        public override string ToString()
        {
            return RangeAddress.ToString();
        }
        public CellClusterKey(CellAddress cell)
            : this(GetRounded(cell.Row ), GetRounded(cell.Column))
        {
            //            Row = (cell.Row.Index / Size) * Size;
            //          Column = (cell.Column.Index / Size) * Size;
        }
        internal static int GetRounded (int index)
        {
            return index/Size*Size;
        }

        internal static IEnumerable<CellClusterKey> GetKeys(Cell cell)
        {
            var address = cell.GetRangeAddress().GetCellAddresses();
            return Enumerable.Distinct(Enumerable.Select(address, a => new CellClusterKey(a)));
        }

        public RangeAddress RangeAddress
        {
            get { return new RangeAddress(new CellAddress(Row, Column), new CellAddress(Row + Size - 1, Column + Size - 1)); }
        }

        public override bool Equals(object obj)
        {
            if (ReferenceEquals(null, obj)) return false;
            if (obj.GetType() != typeof(CellClusterKey)) return false;
            return Equals((CellClusterKey)obj);
        }

        public const int Size = 8;
        public readonly int Row;
        public readonly int Column;

        public CellClusterKey(int row, int column)
        {
            Contract.Requires(GetRounded(row )== row);
            Contract.Requires(GetRounded(column) == column);
            this.Row = row;
            this.Column = column;
        }

        public bool Equals(CellClusterKey other)
        {
            return other.Row == Row && other.Column == Column;
        }

        public override int GetHashCode()
        {
            unchecked
            {
                return (Row * 397) ^ Column;
            }
        }

    }
}